﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "GcmpModelInterface.h"
#include "LinkStatus.h"
#include "IObject.h"
#include <vector>
#include <string>
namespace gcmp
{
    class IDataset;
    class IDocument;
    class IDocumentInitializer;
    class ICollaborationLoadOnDemandManager;


    /// \brief 数据集加载选项
    struct GCMP_MODEL_INTERFACE_EXPORT DatasetLoadOptions
    {
        std::wstring Id;                                    /// < 数据集Id
        int Version  = -1;                                  /// < 版本
        bool Link = false;                                  /// < 是否是链接方式。true为内部调用传入，直接打开数据集请传入false
        std::wstring FilterId;                              /// < 过滤器id
        bool UsingStandardDataOfElement = false;            /// < 是否链接标准数据，true表示链接标准数据，false表示链接非标准数据
        bool IsEditable = false;                            /// < 是否可编辑。非链接方式下，一定可编辑，不用指定此参数
        bool SuggestOpeningThenLinkingRefDatasets = true;   /// < 建议加载的同时，打开并链接参照的数据集
        bool FromLocalFile = false;                         /// < 是否从本地文件加载
        std::wstring LocalFilePullPath;                     /// < 本地文件路径。当FromLocalFile=true时，此参数有效
        bool LinkRefDatasetsOfLatestVersion = false;        /// < 链接参照的工作单元时，是否使用最新的版本
        bool UsingDownloadStatistics = false;               /// < 链接参照的工作单元时，是否进行下载统计
        std::string DamagedJobId;                           /// < 损坏的job id       
        LinkDatasetLoadMode LoadMode = LinkDatasetLoadMode::All; /// < 链接工作单元加载模式
        std::unordered_set<Int64> SpecificElementIds; /// < 当LoadMode为LoadModelAndSpecificElements或OnlyLoadSpecificElements时起作用
        bool LoadLinkElementProxyForLinkDataset = true; /// < 嵌套链接下是否加载链接工作单元的LinkElementProxy数据，只对协同同专业链接生效

        DatasetLoadOptions(const std::wstring& id) : Id(id) {}

        DatasetLoadOptions(const std::wstring& id, int version, bool link)
            : Id(id)
            , Version(version)
            , Link(link)
        {}
    };

    /// \brief 数据集管理器
    ///
    /// 数据集管理器为单例类，负责对数据集进行管理
    FINAL_INTERFACE class GCMP_MODEL_INTERFACE_EXPORT IDatasetManager : public IObject
    {
        DEFINE_CAST_DERIVED(gcmp::IDatasetManager, gcmp::IObject)
    public:
        /// \brief 获取数据集管理器
        /// \return 数据集管理器指针
        static IDatasetManager* Get();

        /// \brief 获取所有数据集
        /// \return std::vector<const IDataset*> 所有数据集
        virtual std::vector<const IDataset*> GetAllDatasets() const = 0;

        /// \brief 获取所有数据集
        /// \return std::vector<const IDataset*> 所有数据集
        virtual std::vector<IDataset*> GetAllDatasets() = 0;

        /// \brief 获取文档关联的数据集
        /// \param pDocument 文档指针
        /// \return const IDataset * 文档关联的数据集
        virtual const IDataset * GetDataset(const IDocument * pDocument) const = 0;

        /// \brief 获取文档关联的数据集
        /// \param pDocument 文档指针
        /// \return IDataset * 文档关联的数据集
        virtual IDataset * GetDataset(IDocument * pDocument) = 0;

        /// \brief 获取数据集
        /// \param datasetId 数据集id
        /// \return pErrorMessage * 错误消息
        GCMP_OBSOLETE_API(2023/01/30, GetDataset(IDocument*, const std::wstring&, std::wstring*))
        virtual IDataset * GetDataset(const std::wstring& datasetId, std::wstring * pErrorMessage) = 0;

        /// \brief 获取当前文链接的数据集
        /// \param pHostDocument 当前文档
        /// \param linkedDatasetId 被链接的数据集id
        /// \param pErrorMessage * 错误消息。如果非空并且有错，传出错误
        /// \return IDataset * 被链接的数据集
        virtual const IDataset* GetDataset(IDocument* pHostDocument, const std::wstring& linkedDatasetId, std::wstring* pErrorMessage) = 0;

        /// \brief 获取当前文链接的数据集集合
        /// \param pHostDocument 当前文档
        /// \param linkedDatasetId 被链接的数据集id
        /// \param pErrorMessage * 错误消息。如果非空并且有错，传出错误
        /// \return std::vector<const IDataset *> 被链接的数据集集合
        virtual std::vector<const IDataset*> GetDatasets(IDocument* pHostDocument, const std::wstring& linkedDatasetId, std::wstring* pErrorMessage) const = 0;

        /// \brief 根据DatasetSubId获取数据集
        /// \param datasetSubId DatasetSubId
        /// \return IDataset * 文档关联的数据集
        GCMP_OBSOLETE_API(2023/01/30, GetDataset(IDocument*, Int32))
        virtual const IDataset* GetDataset(Int32 datasetSubId) const = 0;

        /// \brief 获取当前文档链接的数据集
        /// \param pHostDocument 当前文档
        /// \param linkedDatasetSubId 链接的数据集的subId
        /// \return IDataset * 被链接的数据集
        virtual const IDataset* GetDataset(const IDocument* pHostDocument, Int32 linkedDatasetSubId) const = 0;

        /// \brief 添加一个数据集
        /// \param opDataset 数据集
        /// \return void 空
        virtual void AddDataset(OwnerPtr<IDataset> opDataset) = 0;

        /// \brief 删除一个数据集
        /// \param opDataset 数据集
        /// \return void 空
        virtual void RemoveDataset(const IDataset* pDataset) = 0;

        /// \brief 注册程序所用的文档初始化器
        /// \param opInitializer 数据集指针
        /// \return void 空
        virtual void RegisterDocumentInitializer(OwnerPtr<IDocumentInitializer> opInitializer) = 0;

        /// \brief 获取程序所用的文档初始化器
        /// \return IDocumentInitializer * 文档初始化器指针
        virtual IDocumentInitializer* GetDocumentInitializer() = 0;

        /// \brief 注册协同按需加载管理器
        ///
        /// \param opCollaborationLoadOnDemandManager按需加载管理器
        /// \return 
        virtual void RegisterCollaborationLoadOnDemandManager(OwnerPtr<ICollaborationLoadOnDemandManager> opCollaborationLoadOnDemandManager) = 0;

        /// \brief 获取按需加载管理器
        ///
        /// \return 按需加载管理器
        virtual ICollaborationLoadOnDemandManager* GetCollaborationLoadOnDemandManager() = 0;

        /// \brief 设置数据集的模板文档路径
        /// \return 
        virtual void SetTemplateFilePath(const std::wstring& templateFilePath) = 0;

        /// \brief 获取数据集的模板文档路径
        /// \return 数据集的模板文档路径
        virtual std::wstring GetTemplateFilePath() const = 0;

        /// \brief 设置自动缓存间隔次数(默认是1次)
        /// 
        /// \param interval 间隔次数, 注：值小于1按1处理
        /// \return 
        virtual void SetAutoSaveInterval(int interval) = 0;

        /// \brief 获取自动缓存间隔次数
        /// 
        /// \return 间隔次数
        virtual int GetAutoSaveInterval() const = 0;

        /// \brief 设置自动缓存时间间隔（默认不启用）
        /// 
        /// \param msec 自动缓缓存时间间隔，单位ms
        /// \return 
        virtual void SetAutoSaveTimeInterval(int msec) = 0;

        /// \brief 获取自动缓存时间间隔
        /// 
        /// \return 间隔时间，单位ms
        virtual int GetAutoSaveTimeInterval() const = 0;

        /// \brief 析构函数
        virtual ~IDatasetManager();
    };
}
